/*
 * AhaFirmware.h
 *
 *  Created on: 25 mars 2011
 *      Author: eric
 */

#ifndef AHAFIRMWARE_H_
#define AHAFIRMWARE_H_

#include <Arduino.h>
#include <avr/eeprom.h>
#include "version.h"
#include "AhaTypes.h"
#include "AhaProtocol.h"

// AHA node ID initialisation made by prog waiting ID chip
#define AHA_NODE_ID 1

// Size of different structure
#define AHA_MAX_NV           4
#define AHA_MAX_BINDING      10

#define AHA_NVID_NULL        0xFF
#define AHA_NVID_NOT_SET     0xFE

#define AHA_EEPROM_LOADED    0x63
// Address EEPROM
#define AHA_NODE_LOADED_ADDRESS          0x00
#define AHA_NODE_LOADED_SIZE_BLOCK       1
#define AHA_NODE_ADDRESS_ADDRESS         0x01
#define AHA_NODE_ADDRESS_SIZE_BLOCK      2
#define AHA_NODE_CFG_VERSION_ADDRESS     0x03
#define AHA_NODE_CFG_VERSION_SIZE_BLOCK  2
#define AHA_NODE_BINDING_ADDRESS         0x05
#define AHA_NODE_BINDING_SIZE_BLOCK      3

// NV index
// nviBoutonPoussoirSet
#define NVI_BOUTON_POUSSOIR_SET    0
// nvoBoutonPoussoirStatus
#define NVO_BOUTON_POUSSOIR_STATUS 1
// nviLampeSet
#define NVI_LAMPE_SET              2
// nvoLampeStatus
#define NVO_LAMPE_STATUS           3

// State machine states
#define AHA_STATE_STARTUP    0x00    // Cold/warm reset
#define AHA_STATE_NEED_ID    0x01    // Request node ID
#define AHA_STATE_NEED_CFG   0x02    // Request CFG
#define AHA_STATE_INIT       0x03    // Waiting CFG
#define AHA_STATE_ACTIVE     0x04    // The normal state
#define AHA_STATE_ERROR      0x05    // error state
extern CircularQueue toCanQueue;
extern CircularQueue fromCanQueue;

// specific parameter for this test card
#define CARD_LIGHT_PIN             3
#define CARD_BUTTON_PIN            2
#define CARD_BUTTON_DEBOUNCE_DELAY 50 // the debounce time; increase if the output flickers
class AhaFirmware {
	long previousTime;
	int8_t buttonState; // the current reading from the input pin
	int8_t lastButtonState; // the previous reading from the input pin
	void saveCfg();

public:

	typedef struct {
		uint8_t NVType;
		uint8_t NVDir;
		union {
			void *data;
			AhaTypes::AHA_switch *dSwitch;
		};
	} NETWORKVARIABLE;

	typedef struct {
		uint16_t NVBindingId;
		uint8_t NVID;
	} BINDING;

	NETWORKVARIABLE NVar[AHA_MAX_NV];
	BINDING Binding[AHA_MAX_BINDING];

	byte nodeID[6]; // Node ID
	uint16_t nodeAdr; // Node Address
	uint16_t nodeConfigVersion; // Node configuration version
	uint8_t nodeState; // state machine state
	AhaProtocol ahaProtocol;
	AhaTypes ahaTypes;

	void init();
	void process();
	void resetTimer();

	uint8_t getMajorVersion(void);
	uint8_t getMinorVersion(void);
	uint8_t getSubMinorVersion(void);
	void sendMessage(AhaProtocol::AHA_MSG *ahaMsg);
	uint8_t processInputMessage(Can::CAN_MSG *canMsg);
};

#endif /* AHAFIRMWARE_H_ */
